package wsz.rabbitmq.controller;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import wsz.rabbitmq.entity.Order;
import wsz.rabbitmq.utils.Constants;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 模拟ttl+死信处理
 * @author wsz
 * @date 2022/2/21 16:01
 **/
@RequestMapping(value = "order")
@RestController
public class OrderController {

    @Autowired
    private AmqpTemplate amqpTemplate;

    // 模拟订单表
    private Map<String, Order> orderMap = new HashMap<>(16);

    @RequestMapping("/add")
    public String addOrder() throws UnsupportedEncodingException {

        String uuid = UUID.randomUUID().toString().replaceAll("-", "");

        // 1.新增订单
        Order newOrder = new Order()
                .setUuid(uuid)
                .setPay(Constants.PAY_NO);
        orderMap.put(uuid, newOrder);


        // 2.消息队列-进行异步付款
        final MessageProperties messageProperties = MessagePropertiesBuilder.newInstance()
                .setContentEncoding("utf-8")
                .build();
        // 设置消息的ttl，不设置则使用队列的ttl
//        messageProperties.setExpiration(String.valueOf(second * 1000));

        final Message message = MessageBuilder
                .withBody(uuid.getBytes("utf-8"))
                .andProperties(messageProperties)
                .build();

        amqpTemplate.send(Constants.PAY_EXCHANGE, Constants.PAY_ROUTING_KEY, message);

        System.out.println("订单编号：" + uuid);
        return "订单已生成，请及时付款！uuid=" + uuid;
    }

    /**
     * 获取订单的支付状态
     * @param uuid
     * @return
     */
    @RequestMapping("/payStatus/{uuid}")
    public String getPayStatus(@PathVariable String uuid) {
        if (StringUtils.isEmpty(uuid)) {
            return "无法获取订单信息";
        }
        Order order = orderMap.get(uuid);
        if (order == null) {
            return "订单不存在";
        }
        return Constants.PAY_OK == order.getPay() ? "该订单已付款" : "该订单未付款";
    }


    /**
     * 获取所有订单信息
     * @return
     */
    @RequestMapping("/all")
    public Map<String, Order> getAll() {
        return orderMap;
    }


    /**
     * 手动模拟-调用队列进行消费
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/payQueue")
    public String payQueue() throws UnsupportedEncodingException {
        // 1.获取队列数据
        Object convert = amqpTemplate.receiveAndConvert(Constants.PAY_QUEUEQ);
        if (convert == null) {
            return "订单队列为空";
        }
        // 2.获取订单并模拟付款
        String uuid = new String((byte[]) convert, "utf-8");
        Order order = orderMap.get(uuid);
        if (order == null) {
            return "暂无待支付订单";
        }
        order.setPay(Constants.PAY_OK);
        orderMap.put(uuid, order);

        // 3.返回结果
        String msg = "已付款订单编号=" + uuid;
        System.out.println(msg);
        return msg;
    }

    /**
     * 手动补偿机制
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/dlxQueue")
    public String dlxQueue() throws UnsupportedEncodingException {
        // 1.获取死信队列数据
        Object convert = amqpTemplate.receiveAndConvert(Constants.PAY_QUEUEQ_DLX);
        if (convert == null) {
            return "死信（补偿）队列为空";
        }

        // 2.手动补偿-获取订单并模拟付款
        String dlxUUID = new String((byte[]) convert, "utf-8");
        Order order = orderMap.get(dlxUUID);
        if (order == null) {
            return "暂无待支付订单";
        }
        order.setPay(Constants.PAY_OK);
        orderMap.put(dlxUUID, order);

        String result = "死信（补偿）队列进行业务操作，业务编号=" + dlxUUID;
        System.out.println(result);
        return result;
    }
}
